package com.example.person.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.example.person.common.JsonPage;
import com.example.person.common.ServiceCode;
import com.example.person.common.ServiceException;
import com.example.person.entity.Person;
import com.example.person.entity.PersonDTO;
import com.example.person.entity.PersonExcelVO;
import com.example.person.entity.PersonVO;
import com.example.person.lister.PersonReadLister;
import com.example.person.repository.PersonRepository;
import com.example.person.service.IPersonService;
import com.example.person.utils.IdUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author sytsnb@gmail.com
 * @date 2023 2023/3/10 16:37
 */
@Slf4j
@Service
public class PersonServiceImpl implements IPersonService {

    @Autowired
    private PersonRepository personRepository;

    @Override
    public void addNew(PersonDTO personDTO) {
        Person person = new Person();
        BeanUtils.copyProperties(personDTO, person);
        person.setId(IdUtils.getId());
        person.setCreateTime(LocalDateTime.now());
        person.setUpdateTime(LocalDateTime.now());
        Person i = personRepository.save(person);

        log.info("person  ====== {}", i);
    }

    @Override
    public void deleteById(String id) {
        boolean b = personRepository.existsById(id);
        if (!b) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "id不存在");
        }
        personRepository.deleteById(id);

    }

    @Override
    public void deleteByIds(String[] ids) {
        for (String id : ids) {
            boolean b = personRepository.existsById(id);
            if (!b) {
                throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "id不存在");
            }
        }
        personRepository.deleteAllById(Arrays.asList(ids));
    }

    @Override
//    @Transactional
    public void updateById(String id, PersonDTO personDTO) {
        boolean b = personRepository.existsById(id);
        if (!b) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "更新人员信息失败，尝试访问的数据不存在！");
        }
        Person person = new Person();
        BeanUtils.copyProperties(personDTO, person);
        person.setId(id);
        person.setUpdateTime(LocalDateTime.now());
        personRepository.save(person);
    }

    @Override
    public PersonVO getById(String id) {
        boolean b = personRepository.existsById(id);
        if (!b) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "id不存在");
        }

        Person person = personRepository.getById(id);
        PersonVO personVO = new PersonVO();
//                PersonVO.builder()
//                .id(person.getId())
//                .name(person.getName())
//                .birthDate(person.getBirthDate())
//                .email(person.getEmail())
//                .gender(person.getGender())
//                .idCardType(person.getIdCardType())
//                .mobilePhone(person.getMobilePhone())
//                .fullNameSpelling(person.getFullNameSpelling())
//                .idNo(person.getIdNo())
//                .build();
        BeanUtils.copyProperties(person, personVO);
        return personVO;
    }

    @Override
    public List<PersonVO> getByIds(String[] ids) {

        for (String id : ids) {
            boolean b = personRepository.existsById(id);
            if (!b) {
                throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "id不存在");
            }
        }

        List<Person> personList = personRepository.findAllById(Arrays.asList(ids));

        List<PersonVO> list = new ArrayList<>(personList.size());

        for (Person person : personList) {
            PersonVO personVO = new PersonVO();
            BeanUtils.copyProperties(person, personVO);
            list.add(personVO);
        }
        return list;
    }

    @Override
    public List<PersonVO> selectList() {
        List<Person> personList = personRepository.findAll();
        List<PersonVO> list = new ArrayList<>(personList.size());
        for (int i = 0; i < personList.size(); i++) {
            Person person = personList.get(i);
            PersonVO personVO = new PersonVO();
            BeanUtils.copyProperties(person, personVO);
            list.add(personVO);
        }
        return list;
    }

    @Override
    public List<PersonVO> selectList(PersonDTO personDTO) {

        boolean b = StringUtils.hasLength(personDTO.getName()) || StringUtils.hasLength(personDTO.getEmail()) ||
                StringUtils.hasLength(personDTO.getGender()) || StringUtils.hasLength(personDTO.getIdCardType()) ||
                StringUtils.hasLength(personDTO.getIdNo()) || StringUtils.hasLength(personDTO.getMobilePhone());
        if (b) {
            if (!StringUtils.hasLength(personDTO.getName())) {
                personDTO.setName(" ");
            }
            if (!StringUtils.hasLength(personDTO.getEmail())) {
                personDTO.setEmail(" ");
            }
            if (!StringUtils.hasLength(personDTO.getGender())) {
                personDTO.setGender(" ");
            }
            if (!StringUtils.hasLength(personDTO.getIdCardType())) {
                personDTO.setIdCardType(" ");
            }
            if (!StringUtils.hasLength(personDTO.getIdNo())) {
                personDTO.setIdNo(" ");
            }
            if (!StringUtils.hasLength(personDTO.getMobilePhone())) {
                personDTO.setMobilePhone(" ");
            }
            List<Person> personList =
                    personRepository.findPersonByNameContainingOrIdNoOrMobilePhoneOrEmailOrderByCreateTime(
                            personDTO.getName(), personDTO.getIdNo(), personDTO.getMobilePhone(), personDTO.getEmail());

            List<PersonVO> list =
                    new ArrayList<>(personList.size());
            for (Person person : personList) {
                PersonVO personVO = new PersonVO();
                BeanUtils.copyProperties(person, personVO);
                list.add(personVO);
            }
            return list;
        }


        return selectList();

    }

    @Override
    public JsonPage<PersonVO> list(Integer page, Integer pageSize) {
        return null;
    }


    /**
     * 下载excel模板
     *
     * @param response
     * @throws IOException
     */
    @Override
    public void downloadExcelTemplate(HttpServletResponse response) throws IOException {
        List<PersonExcelVO> list = new ArrayList<>();

        PersonExcelVO personExcelVO = new PersonExcelVO();
        personExcelVO.setName("姓名");
        personExcelVO.setFullNameSpelling("姓名全拼");
        personExcelVO.setGender("性别");
        personExcelVO.setIdCardType("身份证类型");
        personExcelVO.setIdNo("身份证号");
        personExcelVO.setBirthDate("出生日期");
        personExcelVO.setMobilePhone("手机号");
        personExcelVO.setEmail("电子邮箱");

        list.add(personExcelVO);
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为白色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        //居中
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);

        //字体
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 18);
        headWriteCellStyle.setWriteFont(headWriteFont);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetem.sheet;charset=utf-8");
        response.setCharacterEncoding("utf-8");

        //要导出的文件名
        String fileName = URLEncoder.encode("人员信息数据模板", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream())
                .head(Object.class)
                .excelType(ExcelTypeEnum.XLSX)
                //表中左下角的名字
                .sheet("人员信息表模板")
                .registerWriteHandler(new SimpleColumnWidthStyleStrategy(20))
                .doWrite(list);
    }

    @Override
    public void exportExcel(HttpServletResponse response, String[] ids) throws IOException {
        List<Person> list = new ArrayList<>();
        if (ids.length > 0) {
            list = personRepository.findAllById(Arrays.asList(ids));
        } else {
            list = personRepository.findAll();
        }
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为白色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 13);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

        //设置边框
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);

        // 背景白色
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short) 13);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetem.sheet;charset=utf-8");
        response.setCharacterEncoding("utf-8");

        //要导出的文件名
        String fileName = URLEncoder.encode("人员信息", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

        EasyExcel.write(response.getOutputStream())
                .head(PersonVO.class)
                .excelType(ExcelTypeEnum.XLSX)
                //表中左下角的名字
                .sheet("人员信息表")
                .registerWriteHandler(horizontalCellStyleStrategy)
                .doWrite(list);
    }

    @Override
    public void uploadExcel(MultipartFile file) throws IOException {
        EasyExcel.read(
                file.getInputStream(),
                PersonVO.class,
                new PersonReadLister(personRepository))
                .sheet(0)
                .headRowNumber(1)
                .doRead();
    }
}
